package com.weng.cloud.starter.redis.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.weng.cloud.starter.redis.service.SerializedRedisService;
import com.weng.cloud.starter.redis.service.impl.SerializedRedisServiceImpl;
import com.weng.cloud.starter.redis.template.SerializedRedisTemplate;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;


@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class SerializedRedisServiceAutoConfiguration {


    /**
     * 设置RedisTemplate规则
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public SerializedRedisTemplate<String,Object> serializedRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        SerializedRedisTemplate<String,Object> serializedRedisTemplate = new SerializedRedisTemplate<>();
        serializedRedisTemplate.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

        //解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        // 指定要序列化的域，field,get和set,以及修饰符范围，ANY是都有包括private和public
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化输入的类型，类必须是非final修饰的，final修饰的类，比如String,Integer等会跑出异常
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        //序列号key value
        serializedRedisTemplate.setKeySerializer(new StringRedisSerializer());
        serializedRedisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        serializedRedisTemplate.setHashKeySerializer(new StringRedisSerializer());
        serializedRedisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);

        serializedRedisTemplate.afterPropertiesSet();
        return serializedRedisTemplate;
    }


    @Bean
    public SerializedRedisService serializedRedisService(SerializedRedisTemplate<String,Object> serializedRedisTemplate){
        return new SerializedRedisServiceImpl(serializedRedisTemplate);
    }


}